package cc.vv.lkimagecomponent2.loaderplugin;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.FloatRange;
import android.support.annotation.IntRange;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.Animation;
import android.widget.ImageView;

import java.io.File;

import cc.vv.lkimagecomponent2.initplugin.InitPlugin;
import cc.vv.lkimagecomponent2.lib.Contants;
import cc.vv.lkimagecomponent2.lib.mode.AnimationMode;
import cc.vv.lkimagecomponent2.lib.mode.DiskCacheMode;
import cc.vv.lkimagecomponent2.lib.mode.PriorityMode;
import cc.vv.lkimagecomponent2.lib.mode.ScaleMode;
import cc.vv.lkimagecomponent2.lib.mode.ShapeMode;
import cc.vv.lkimagecomponent2.loaderplugin.util.ImageUtil;
import cc.vv.lklibrary.log.LogOperate;

/**
 * @author dupeng dupeng@vv.cc
 * @date 2018/3/14
 */

public class LoadConfig {
    /**
     * context
     */
    private Context context;
    /**
     * 加载url
     */
    private String url;
    /**
     * 缩略图缩放倍数
     */
    private float thumbnail;
    /**
     * 加载的文件路径
     */
    private String filePath;
    /**
     * 加载的文件
     */
    private File file;

    /**
     * 加载的资源id
     */
    private int resId;
    /**
     * 加载的raw路径
     */
    private int rawId;
    /**
     * 加载的assets路径
     */
    private String assertspath;
    /**
     * 加载的内容提供者路径
     */
    private String contentProvider;
    /**
     * 是否是gif图片
     */
    private boolean isGif;
    /**
     * 加载图片的view
     */
    private View target;
    /**
     * 重写的宽
     */
    private int oWidth;
    /**
     * 重写的高
     */
    private int oHeight;
    /**
     * 是否需要晕映
     */
    private boolean isNeedVignette;
    /**
     * 是否需要素描
     */
    private boolean isNeedSketch;
    /**
     * 马赛克等级
     */
    private float pixelationLevel;
    /**
     * 是否需要马赛克
     */
    private boolean isNeedPixelation;

    /**
     * 是否需要胶片
     */
    private boolean isNeedInvert;
    /**
     * 锐化等级
     */
    private float contrastLevel;
    /**
     * 是否需要锐化
     */
    private boolean isNeedContrast;
    /**
     * 是否需要墨画
     */
    private boolean isNeedSepia;
    /**
     * 是否需要油画
     */
    private boolean isNeedToon;
    /**
     * 是否需要漩涡
     */
    private boolean isNeedSwirl;
    /**
     * 是否需要黑色
     */
    private boolean isNeedGrayscale;
    /**
     * 是否需要亮度
     */
    private boolean isNeedBrightness;
    /**
     * 是否需要亮度
     */
    private float brightnessLeve;
    /**
     * 是否需要模糊
     */
    private boolean needBlur;
    /**
     * 是否过滤颜色
     */
    private boolean needFilteColor;
    /**
     * 过滤颜色
     */
    private int filteColor;

    /**
     * 设置加载紧急程度
     */
    private PriorityMode priority;
    /**
     * 动画类型
     */
    private AnimationMode animationType;
    /**
     * 动画id
     */
    private int animationId;
    /**
     * 动画
     */
    private Animation animation;
    /**
     * 模糊半径
     */
    private int blurRadius;
    /**
     * 占位图
     */
    private int placeHolderResId;
    /**
     * error占位图
     */
    private int errorResId;
    /**
     * 占位图
     */
    private Drawable placeHolderDrawable;
    /**
     * error占位图
     */
    private Drawable errorDrawable;
    /**
     * 是否只获取bitmap
     */
    private boolean asBitmap;
    /**
     * /默认矩形,可选直角矩形,圆形/椭圆
     */
    private ShapeMode shapeMode;
    /**
     * 圆角矩形时圆角的半径
     */
    private int rectRoundRadius;
    /**
     * 磁盘存储模式
     */
    private DiskCacheMode diskCacheStrategy;
    /**
     * 填充模式,默认centercrop,可选fitXY,centerInside...
     */
    private ScaleMode scaleMode;
    /**
     * 如果为gif,动画播放次数.-1:永久 0:不动  N:次数
     */
    private int gifRepeatCount = -1;

    /**
     * 是否crossFade动画
     */
    private boolean isCrossFade = false;

    /**
     * 是否执行动画
     */
    private boolean isAnim = true;

    /**
     * fade动画时长，如果为0，则使用glide默认时长
     */
    private int crossFadeDuration = 0;

    /**
     * bitmap模式的回调
     */
    private BitmapListener bitmapListener;

    /**
     * view设置图片回调
     */
    private TargetViewCallback targetViewCallback;

    public LoadConfig(ConfigBuilder builder) {
        this.context = builder.getContext();
        this.url = builder.url;
        this.isCrossFade = builder.isCrossFade;
        this.crossFadeDuration = builder.crossFadeDuration;
        this.thumbnail = builder.thumbnail;
        this.filePath = builder.filePath;
        this.file = builder.file;
        this.resId = builder.resId;
        this.rawId = builder.rawId;
        this.assertspath = builder.assertspath;
        this.contentProvider = builder.contentProvider;
        this.target = builder.target;
        this.oWidth = builder.oWidth;
        this.oHeight = builder.oHeight;
        this.shapeMode = builder.shapeMode;
        if (shapeMode == ShapeMode.RECT_ROUND) {
            this.rectRoundRadius = builder.rectRoundRadius;
        }
        this.scaleMode = builder.scaleMode;
        this.diskCacheStrategy = builder.diskCacheStrategy;
        this.isAnim = builder.isAnimation;
        this.animationId = builder.animationId;
        this.animationType = builder.animationType;
        this.animation = builder.animation;
        this.priority = builder.priority;
        //滤镜
        //是否需要晕映
        this.isNeedVignette = builder.isNeedVignette;
        //是否需要素描
        this.isNeedSketch = builder.isNeedSketch;
        //是否需要马赛克
        this.pixelationLevel = builder.pixelationLevel;
        //是否需要马赛克
        this.isNeedPixelation = builder.isNeedPixelation;
        //是否需要胶片
        this.isNeedInvert = builder.isNeedInvert;
        this.contrastLevel = builder.contrastLevel;
        this.isNeedContrast = builder.isNeedContrast;
        this.isNeedSepia = builder.isNeedSepia;
        this.isNeedToon = builder.isNeedToon;
        this.isNeedSwirl = builder.isNeedSwirl;
        this.isNeedGrayscale = builder.isNeedGrayscale;
        this.isNeedBrightness = builder.isNeedBrightness;
        //是否需要亮度
        this.brightnessLeve = builder.brightnessLeve;
        this.filteColor = builder.filteColor;
        this.needBlur = builder.needBlur;
        this.needFilteColor = builder.needFilteColor;
        this.placeHolderResId = builder.placeHolderResId;
        this.placeHolderDrawable = builder.placeHolderDrawable;
        this.errorDrawable = builder.errorDrawable;
        this.asBitmap = builder.asBitmap;
        this.bitmapListener = builder.bitmapListener;
        this.isGif = builder.isGif;
        this.blurRadius = builder.blurRadius;
        this.errorResId = builder.errorResId;
        this.gifRepeatCount = builder.gifRepeatCount;
        this.targetViewCallback = builder.targetViewCallback;
    }

    public boolean isAsBitmap() {
        return asBitmap;
    }

    public boolean isCrossFade() {
        return isCrossFade;
    }

    public boolean isAnim() {
        return isAnim;
    }

    public int getGifRepeatCount() {
        return gifRepeatCount;
    }

    public int getCrossFadeDuration() {
        return crossFadeDuration;
    }

    public DiskCacheMode getDiskCacheStrategy() {
        return diskCacheStrategy;
    }

    public int getErrorResId() {
        return errorResId;
    }

    public String getContentProvider() {
        return contentProvider;
    }

    public TargetViewCallback getTargetViewCallback() {
        return targetViewCallback;
    }

    public Context getContext() {
        return context;
    }

    public String getFilePath() {
        return filePath;
    }

    public File getFile() {
        return file;
    }

    public boolean isNeedBlur() {
        return needBlur;
    }

    public int getPlaceHolderResId() {
        return placeHolderResId;
    }

    public int getRectRoundRadius() {
        return rectRoundRadius;
    }

    public int getResId() {
        return resId;
    }

    public int getRawId() {
        return rawId;
    }

    public String getAssertspath() {
        return assertspath;
    }

    public ScaleMode getScaleMode() {
        return scaleMode;
    }

    public ShapeMode getShapeMode() {
        return shapeMode;
    }

    public View getTarget() {
        return target;
    }

    public String getUrl() {
        return url;
    }

    public int getoWidth() {
        return oWidth;
    }

    public int getoHeight() {
        return oHeight;
    }

    public AnimationMode getAnimationType() {
        return animationType;
    }

    public int getAnimationId() {
        return animationId;
    }

    public Animation getAnimation() {
        return animation;
    }

    public PriorityMode getPriority() {
        return priority;
    }

    public int getFilteColor() {
        return filteColor;
    }

    public float getContrastLevel() {
        return contrastLevel;
    }

    public boolean isNeedFilteColor() {
        return needFilteColor;
    }

    public float getBrightnessLeve() {
        return brightnessLeve;
    }

    public boolean isNeedBrightness() {
        return isNeedBrightness;
    }

    public BitmapListener getBitmapListener() {
        return bitmapListener;
    }

    public float getThumbnail() {
        return thumbnail;
    }

    public boolean isGif() {
        return isGif;
    }

    public int getBlurRadius() {
        return blurRadius;
    }

    public boolean isNeedGrayscale() {
        return isNeedGrayscale;
    }

    public boolean isNeedSwirl() {
        return isNeedSwirl;
    }

    public Drawable getPlaceHolderDrawable() {
        return placeHolderDrawable;
    }

    public Drawable getErrorDrawable() {
        return errorDrawable;
    }

    public boolean isNeedToon() {
        return isNeedToon;
    }

    public boolean isNeedSepia() {
        return isNeedSepia;
    }

    public boolean isNeedContrast() {
        return isNeedContrast;
    }

    public boolean isNeedInvert() {
        return isNeedInvert;
    }

    public boolean isNeedPixelation() {
        return isNeedPixelation;
    }

    public float getPixelationLevel() {
        return pixelationLevel;
    }

    public boolean isNeedSketch() {
        return isNeedSketch;
    }

    public boolean isNeedVignette() {
        return isNeedVignette;
    }

    /**
     * 配置完成，最后调用此方法，开始执行。
     */
    private void show() {
        LoadPlugin.getInstance().build(this);
    }



    public static class ConfigBuilder {

        private final Context context;

        private String url;
        private float thumbnail;
        private String filePath;
        private File file;
        private int resId;
        private int rawId;
        private String assertspath;
        private String contentProvider;
        private boolean isGif = false;
        private View target;

        private boolean asBitmap;
        private BitmapListener bitmapListener;
        private int oWidth;

        private int oHeight;
        //滤镜
        private boolean isNeedVignette;

        private boolean isNeedSketch;
        private float pixelationLevel;
        private boolean isNeedPixelation;
        private boolean isNeedInvert;
        private float contrastLevel;
        private boolean isNeedContrast = false;
        private boolean isNeedSepia = false;
        private boolean isNeedToon = false;
        private boolean isNeedSwirl = false;
        private boolean isNeedGrayscale = false;
        private boolean isNeedBrightness = false;
        private float brightnessLeve;
        private boolean needBlur = false;
        private boolean needFilteColor = false;
        private int blurRadius;
        private int placeHolderResId;
        private Drawable placeHolderDrawable;
        private int errorResId;
        private Drawable errorDrawable;
        private ShapeMode shapeMode = ShapeMode.RECT;
        private int rectRoundRadius = 0;
        private DiskCacheMode diskCacheStrategy = DiskCacheMode.AUTOMATIC;
        private ScaleMode scaleMode = ScaleMode.FIT_CENTER;

        private PriorityMode priority = PriorityMode.PRIORITY_IMMEDIATE;
        private int filteColor;
        private int animationId;
        private AnimationMode animationType;
        private Animation animation;
        private boolean isCrossFade = false;
        private int crossFadeDuration = 0;
        private boolean isAnimation = true;
        private TargetViewCallback targetViewCallback;
        private int gifRepeatCount = InitPlugin.getInstance().mConfig == null ?
                -1 : InitPlugin.getInstance().mConfig.getGifRepeatCount();

        public ConfigBuilder(Context context) {
            this.context = context;
        }

        /**
         * 添加fade动画,时长是默认
         *
         * @return
         */
        public ConfigBuilder crossFade() {
            isCrossFade = true;
            return this;
        }

        /**
         * 如果为gif时,播放次数
         *
         * @param count -1:永久  0: 不播放  N:N次
         * @return
         */
        public ConfigBuilder gifRepeatCount(@IntRange(from = -1) int count) {
            gifRepeatCount = count;
            return this;
        }

        /**
         * 添加fade动画
         *
         * @param duration
         * @return
         */
        public ConfigBuilder crossFade(int duration) {
            if (duration > 0) {
                isCrossFade = true;
                crossFadeDuration = duration;
            }
            return this;
        }

        /**
         * 缩略图
         *
         * @param thumbnail
         * @return
         */
        public ConfigBuilder thumbnail(float thumbnail) {
            this.thumbnail = thumbnail;
            return this;
        }

        /**
         * error图
         * <b>注意：如果是svg，请使用{@link LoadConfig.ConfigBuilder#error(Drawable)}</b>
         *
         * @param errorResId
         * @return
         */
        public ConfigBuilder error(int errorResId) {
            this.errorResId = errorResId;
            return this;
        }

        /**
         * error图
         *
         * @param errorDrawable
         * @return
         */
        public ConfigBuilder error(Drawable errorDrawable) {
            this.errorDrawable = errorDrawable;
            return this;
        }

        /**
         * 设置路径.目前与loadUrl()功能一样
         * 这里匹配：1.http 2.uri 3.文件路径也可以啦!
         *
         * @param urlPath
         * @return
         */
        public ConfigBuilder load(String urlPath) {
            if (TextUtils.isEmpty(urlPath)) {
                return this;
            }
            this.url = urlPath;
            if (url.endsWith(Contants.GIT_SUFFIX)) {
                isGif = true;
            }
            return this;
        }

        /**
         * 设置路径.
         * 这里匹配：1.http 2.uri 3.文件路径也可以啦!
         *
         * @param url
         * @return
         * @deprecated 与 {@link LoadConfig.ConfigBuilder#load(String)} 作用相同.
         */
        public ConfigBuilder loadUrl(String url) {
            if (TextUtils.isEmpty(url)) {
                return this;
            }
            this.url = url;
            if (url.endsWith(Contants.GIT_SUFFIX)) {
                isGif = true;
            }
            return this;
        }

        /**
         * 加载SD卡资源
         *
         * @param filePath
         * @return
         *
         */
        public ConfigBuilder loadFile(String filePath) {
            if (TextUtils.isEmpty(filePath)) {
                return this;
            }
            if (!new File(filePath).exists()) {
                //throw new RuntimeException("文件不存在");
                LogOperate.e("图片文件不存在：" + filePath);
                return this;
            }

            this.filePath = filePath;
            if (filePath.endsWith(Contants.GIT_SUFFIX)) {
                isGif = true;
            }
            return this;
        }

        /**
         * 加载SD卡资源
         *
         * @param file
         * @return
         */
        public ConfigBuilder loadFile(File file) {
            this.file = file;
            if (file == null || !file.exists()) {
                return this;
            }
            if (file.getAbsolutePath().endsWith(Contants.GIT_SUFFIX)) {
                isGif = true;
            }
            if ("gif".equals(ImageUtil.getRealType(file))) {
                isGif = true;
            }
            return this;
        }

        /**
         * 加载drawable资源
         *
         * @param resId
         * @return
         */
        public ConfigBuilder loadRes(int resId) {
            this.resId = resId;
            return this;
        }

        /**
         * 加载ContentProvider资源
         *
         * @param contentProvider
         * @return
         */
        public ConfigBuilder loadContent(String contentProvider) {
            if (contentProvider.startsWith("content:")) {
                this.contentProvider = contentProvider;
                return this;
            }

            if (contentProvider.contains("gif")) {
                isGif = true;
            }

            return this;
        }

        /**
         * 加载raw资源
         *
         * @param rawId
         * @return
         */
        public ConfigBuilder loadRaw(int rawId) {
            this.rawId = rawId;
            return this;
        }

        /**
         * 加载asserts资源
         *
         * @param assertspath 资源在assets文件下的路径。
         * @return
         */
        public ConfigBuilder loadAsserts(String assertspath) {
            this.assertspath = assertspath;

            if (assertspath.endsWith(Contants.GIT_SUFFIX)) {
                isGif = true;
            }

            return this;
        }

        /**
         * 设置到的view
         *
         * @param targetView
         */
        public void into(ImageView targetView) {
            this.target = targetView;
            new LoadConfig(this).show();
        }

        /**
         * 作为bitmap返回
         *
         * @param bitmapListener 主线程回调
         */
        public void asBitmap(BitmapListener bitmapListener) {
            this.bitmapListener = bitmapListener;
            this.asBitmap = true;
            new LoadConfig(this).show();
        }

        /**
         * 加载图片的分辨率
         *
         * @param oWidth  dp
         * @param oHeight dp
         * @return
         */
        public ConfigBuilder override(int oWidth, int oHeight) {
            this.oWidth = ImageUtil.dip2px(oWidth);
            this.oHeight = ImageUtil.dip2px(oHeight);
            return this;
        }

        /**
         * 占位图
         *
         * @param placeHolderResId
         * @return
         */
        public ConfigBuilder placeHolder(int placeHolderResId) {
            this.placeHolderResId = placeHolderResId;
            return this;
        }

        /**
         * 占位图
         *
         * @param placeHolderDrawable
         * @return
         */
        public ConfigBuilder placeHolder(Drawable placeHolderDrawable) {
            this.placeHolderDrawable = placeHolderDrawable;
            return this;
        }

        public Context getContext() {
            return context;
        }

        /**
         * 是否需要高斯模糊
         *
         * @param blurRadius 0-25
         * @return
         */
        public ConfigBuilder blur(@IntRange(from = 0, to = 25) int blurRadius) {
            this.needBlur = true;
            this.blurRadius = blurRadius;
            return this;
        }

        /**
         * 圆角
         *
         * @return
         */
        public ConfigBuilder asCircle() {
            this.shapeMode = ShapeMode.OVAL;
            return this;
        }

        /**
         * 形状为圆角矩形时的圆角半径
         *
         * @param rectRoundRadius
         * @return
         */
        public ConfigBuilder rectRoundCorner(int rectRoundRadius) {
            this.rectRoundRadius = ImageUtil.dip2px(rectRoundRadius);
            this.shapeMode = ShapeMode.RECT_ROUND;
            return this;
        }

        /**
         * 正方形
         *
         * @return
         */
        public ConfigBuilder asSquare() {
            this.shapeMode = ShapeMode.SQUARE;
            return this;
        }

        /**
         * 磁盘缓存
         */
        public ConfigBuilder diskCacheStrategy(DiskCacheMode diskCacheStrategy) {
            this.diskCacheStrategy = diskCacheStrategy;
            return this;
        }

        /**
         * 拉伸/裁剪模式
         *
         * @param scaleMode 取值ScaleMode
         * @return
         */
        public ConfigBuilder scale(ScaleMode scaleMode) {
            this.scaleMode = scaleMode;
            return this;
        }

        /**
         * 不执行动画
         *
         * @return
         */
        public ConfigBuilder dontAnim() {
            this.isAnimation = false;
            return this;
        }

        /**
         * 动画
         *
         * @param animationId
         * @return
         */
        public ConfigBuilder animate(int animationId) {
            this.animationType = AnimationMode.ANIMATIONID;
            this.animationId = animationId;
            return this;
        }

        /**
         * 动画
         *
         * @param animation
         * @return
         */
        public ConfigBuilder animate(Animation animation) {
            this.animationType = AnimationMode.ANIMATION;
            this.animation = animation;
            return this;
        }

        /**
         * 加载优先级
         *
         * @param priority
         * @return
         */
        public ConfigBuilder priority(PriorityMode priority) {
            this.priority = priority;
            return this;
        }

        /**
         * 颜色遮罩
         *
         * @param filteColor
         * @return
         */
        public ConfigBuilder colorFilter(int filteColor) {
            this.filteColor = filteColor;
            this.needFilteColor = true;
            return this;
        }

        /**
         * 增加亮度
         *
         * @param level brightness value ranges from -1.0 to 1.0, with 0.0 as the normal level
         * @return
         */
        public ConfigBuilder brightnessFilter(@FloatRange(from = -1f, to = 1f) float level) {
            this.isNeedBrightness = true;
            this.brightnessLeve = level;
            return this;
        }

        /**
         * 灰度化
         *
         * @return
         */
        public ConfigBuilder grayscaleFilter() {
            this.isNeedGrayscale = true;
            return this;
        }

        /**
         * 旋涡效果
         *
         * @return
         */
        public ConfigBuilder swirlFilter() {
            this.isNeedSwirl = true;
            return this;
        }

        /**
         * 油画效果
         *
         * @return
         */
        public ConfigBuilder toonFilter() {
            this.isNeedToon = true;
            return this;
        }

        /**
         * 墨化
         *
         * @return
         */
        public ConfigBuilder sepiaFilter() {
            this.isNeedSepia = true;
            return this;
        }

        /**
         * 对比度设置
         *
         * @param constrasrLevel ranges from 0.0 to 4.0, with 1.0 as the normal level
         * @return
         */
        public ConfigBuilder contrastFilter(@FloatRange(from = 0f, to = 4f) float constrasrLevel) {
            this.contrastLevel = constrasrLevel;
            this.isNeedContrast = true;
            return this;
        }

        /**
         * 胶片效果
         *
         * @return
         */
        public ConfigBuilder invertFilter() {
            this.isNeedInvert = true;
            return this;
        }

        /**
         * 素描效果
         *
         * @return
         */
        public ConfigBuilder sketchFilter() {
            this.isNeedSketch = true;
            return this;
        }

        /**
         * 像素画效果
         *
         * @param pixelationLevel 默认是10
         * @return
         */
        public ConfigBuilder pixelationFilter(float pixelationLevel) {
            this.pixelationLevel = pixelationLevel;
            this.isNeedPixelation = true;
            return this;
        }

        /**
         * 光晕效果
         *
         * @return
         */
        public ConfigBuilder vignetteFilter() {
            this.isNeedVignette = true;
            return this;
        }

        /**
         * 如果设置到的view是非Imageview,就用此方法.
         * 注意:动画,crossfade 暂不支持
         *
         * @param callback
         * @return
         */
        public void into(TargetViewCallback callback) {
            this.targetViewCallback = callback;
            new LoadConfig(this).show();
        }

    }

}
